package guggaTests.tasks
{
	import flexunit.framework.Assert;
	import flexunit.framework.TestCase;
	
	import gugga.eventHelpers.EventDescriptor;
	import gugga.tasks.FictiveTask;
	import gugga.tasks.ITask;
	import gugga.tasks.PreconditionsTask;
	import gugga.tasks.helpers.IPreconditionsManager;
	import gugga.tasks.helpers.PreconditionsManager;
	import gugga.tasks.helpers.PreconditionsManagerEvent;

	public class PreconditionsTaskTest extends TestCase
	{
		import gugga.tasks.events.TaskEvent;
		
		public function PreconditionsTaskTest()
		{
			super();
		}
		
		public function testStartWithoutPreconditions() : void
		{
			var isAccepting:Boolean = true;
			var preconditionsManager : IPreconditionsManager = new PreconditionsManager(isAccepting);
		
			// initialize PreconditionsTask with preconditionsManager:
			var preconditionsTask : ITask = new PreconditionsTask(preconditionsManager);
		
			//preconditionsTask.addEventListener(TaskEvent.START,	startEventFunction);
			preconditionsTask.addEventListener(TaskEvent.START, addAsync(verifyRunning, 1400,
			new TaskExpectedStateDescriptor("PreconditionsTask", preconditionsTask, "started", false)));
			
			preconditionsTask.addEventListener(TaskEvent.COMPLETED, addAsync(verifyRunning, 1400,
			new TaskExpectedStateDescriptor("PreconditionsTask", preconditionsTask, "completed", false)));
			
			preconditionsTask.start();
		}
		
		public function testNotCompletedWhenNotStartedPreconditionsMetBeforeInitialization() : void
		{
			var isAccepting:Boolean = true
			
			var preconditionsManager : IPreconditionsManager = new PreconditionsManager(isAccepting);
		
			var eventSource1 : FictiveTask = new FictiveTask();
			var precondition1 : EventDescriptor = new EventDescriptor(
					eventSource1, 
					TaskEvent.START);
			preconditionsManager.add(precondition1);
			
			var eventSource2 : FictiveTask = new FictiveTask();
			var precondition2 : EventDescriptor = new EventDescriptor(
					eventSource2, 
					TaskEvent.START);
			preconditionsManager.add(precondition2);
	
			// meet preconditions before PreconditionsTask init:
			eventSource1.start();
			eventSource2.start();			
			
			// initialize PreconditionsTask with preconditionsManager:
			var preconditionsTask:ITask = new PreconditionsTask(preconditionsManager)	
	
				preconditionsTask.addEventListener(TaskEvent.COMPLETED, addAsync(invalidTestIndicator, 1400,
			null, validTestIndicator));
		}
		
		public function testNotCompletedWhenNotStartedPreconditionsMetAfterInitialization() : void
		{
			var isAccepting:Boolean = true
			
			var preconditionsManager : IPreconditionsManager = new PreconditionsManager(isAccepting);
		
			var eventSource1 : FictiveTask = new FictiveTask();
			var precondition1 : EventDescriptor = new EventDescriptor(
					eventSource1, 
					TaskEvent.START);
			preconditionsManager.add(precondition1);
			
			var eventSource2 : FictiveTask = new FictiveTask();
			var precondition2 : EventDescriptor = new EventDescriptor(
					eventSource2, 
					TaskEvent.START);
			preconditionsManager.add(precondition2);
	
			// initialize PreconditionsTask with preconditionsManager:
			var preconditionsTask:ITask = new PreconditionsTask(preconditionsManager)	
	
				preconditionsTask.addEventListener(TaskEvent.COMPLETED, addAsync(invalidTestIndicator, 1400,
			null, validTestIndicator));
	
			// meet preconditions before PreconditionsTask start:
			eventSource1.start();
			eventSource2.start();
		}
		
		public function testCompletedWhenStartedPrecondtionsMetAfterInitialization() : void
		{
			var isAccepting:Boolean = true
			
			var preconditionsManager : IPreconditionsManager = new PreconditionsManager(isAccepting);
		
			var eventSource1 : FictiveTask = new FictiveTask();
			var precondition1 : EventDescriptor = new EventDescriptor(
					eventSource1, 
					TaskEvent.START);
			preconditionsManager.add(precondition1);
			
			var eventSource2 : FictiveTask = new FictiveTask();
			var precondition2 : EventDescriptor = new EventDescriptor(
					eventSource2, 
					TaskEvent.START);
			preconditionsManager.add(precondition2);
	
			// initialize PreconditionsTask with preconditionsManager:
			var preconditionsTask:ITask = new PreconditionsTask(preconditionsManager)	
		
			preconditionsTask.addEventListener(TaskEvent.START, addAsync(validTestIndicator, 300));
			
			preconditionsTask.addEventListener(TaskEvent.COMPLETED, addAsync(verifyRunning, 300,
				new TaskExpectedStateDescriptor("PreconditionsTask", preconditionsTask, "completed", false)));
		
			// meet preconditions before PreconditionsTask start:
			eventSource1.start();
			eventSource2.start();
			
			preconditionsTask.start();		
		}
		
		public function testCompletedWhenStartedPreconditionsNotMet() : void
		{
			var isAccepting:Boolean = true
			
			var preconditionsManager : IPreconditionsManager = new PreconditionsManager(isAccepting);
		
			var eventSource1 : FictiveTask = new FictiveTask();
			var precondition1 : EventDescriptor = new EventDescriptor(
					eventSource1, 
					TaskEvent.START);
			preconditionsManager.add(precondition1);
			
			var eventSource2 : FictiveTask = new FictiveTask();
			var precondition2 : EventDescriptor = new EventDescriptor(
					eventSource2, 
					TaskEvent.START);
			preconditionsManager.add(precondition2);
	
			// initialize PreconditionsTask with preconditionsManager:
			var preconditionsTask:ITask = new PreconditionsTask(preconditionsManager)	
		
			preconditionsTask.addEventListener(TaskEvent.START, addAsync(validTestIndicator, 300));
			
			preconditionsTask.addEventListener(TaskEvent.COMPLETED, addAsync(invalidTestIndicator, 300,
				null, validTestIndicator));
					
			preconditionsTask.start();			
		}
		
		public function testIsImmediatelyInterruptable() : void
		{
			var isAccepting:Boolean = true;
			var preconditionsManager:IPreconditionsManager 
				= new PreconditionsManager(isAccepting);
			
			// initialize PreconditionsTask with preconditionsManager:
			var preconditionsTask:ITask 
				= new PreconditionsTask(preconditionsManager);
			
			assertTrue(
					"PreconditionsTask should be immediately interruptable", 
					preconditionsTask.isImmediatelyInterruptable());
		}

		public function testInterrupt() : void
		{
			var isAccepting:Boolean = true
			
			var preconditionsManager : IPreconditionsManager = new PreconditionsManager(isAccepting);
		
			var eventSource1 : FictiveTask = new FictiveTask();
			var precondition1 : EventDescriptor = new EventDescriptor(
					eventSource1, 
					TaskEvent.START);
			preconditionsManager.add(precondition1);
			
			var eventSource2 : FictiveTask = new FictiveTask();
			var precondition2 : EventDescriptor = new EventDescriptor(
					eventSource2, 
					TaskEvent.START);
			preconditionsManager.add(precondition2);
	
			// initialize PreconditionsTask with preconditionsManager:
			var preconditionsTask:ITask = new PreconditionsTask(preconditionsManager)
			
			preconditionsTask.start();
			preconditionsTask.interrupt();
			
			
			//task can't complete while interupted
			preconditionsTask.addEventListener(TaskEvent.COMPLETED, addAsync(invalidTestIndicator, 300,
				null, validTestIndicator));
					
			eventSource1.start();
			eventSource2.start();			
		}
		
		private function invalidTestIndicator(aTaskEvent : TaskEvent, aMessge : String = null) : void
		{
			if(!aMessge)
			{
				aMessge = "Invalid Test"
			}
			
			assertFalse(aMessge, true);
		}
		
		private function validTestIndicator(aTaskEvent : TaskEvent, aData : Object = null) : void
		{
			//indicates the test was valid
		}
		
		private function verifyRunning(aTaskEvent : TaskEvent,
			aTaskExpectedStateDescriptor : TaskExpectedStateDescriptor) : void
		{
			assertEquals(
				 aTaskExpectedStateDescriptor.TaskName + "isRunning have to be not " + aTaskExpectedStateDescriptor.Task.isRunning().toString()  
					+ ", becouse task is " + aTaskExpectedStateDescriptor.TaskExpectedStateString,
				aTaskExpectedStateDescriptor.Task.isRunning(),
				aTaskExpectedStateDescriptor.TaskExpectedState
				)
		}	
	}
}

	import gugga.tasks.ITask;
	

	class TaskExpectedStateDescriptor
	{
		public var TaskName : String;
		public var Task : ITask
		
		public var TaskExpectedStateString : String;
		public var TaskExpectedState : Boolean;

		
		public function TaskExpectedStateDescriptor(aTaskName : String, aTask : ITask, aTaskExpectedStateString : String, 
			aTaskExpectedState : Boolean)
		{
			TaskName = aTaskName;
			Task = aTask;
			
			TaskExpectedState = aTaskExpectedState;
			TaskExpectedStateString = aTaskExpectedStateString;
		}
	}
	
